<template>
    <el-form ref="formRef" :model="form" :rules="rules">
        <el-form-item prop="phone">
            <el-input v-model="form.phone" placeholder="请输入手机号码" prefix-icon="el-icon-cellphone" />
        </el-form-item>
        <el-form-item prop="code">
            <el-input v-model="form.code" placeholder="请输入验证码" maxlength="6" prefix-icon="el-icon-message">
                <template #append>
                    <el-button :disabled="state.disabled" link @click="handleGetCode">
                        {{ state.codeText }}
                    </el-button>
                </template>
            </el-input>
        </el-form-item>
        <el-form-item>
            <el-checkbox-group v-model="form.remember">
                <el-checkbox label="记住我" name="type" />
            </el-checkbox-group>
        </el-form-item>
        <el-button class="btn-login" type="primary" @click="handleLogin">登录</el-button>
    </el-form>
    <Captcha
        ref="captchaRef"
        v-model:disabled="state.disabled"
        v-model:text="state.codeText"
        unique-key="login/phone"
        keep-running
        :duration="props.smsDelay"
    />
</template>

<script setup>
import { reactive, ref } from "vue";

import Captcha from "@/components/captcha.vue";

const emits = defineEmits(["login"]);
const props = defineProps({
    smsDelay: { type: [String, Number], required: true },
    getSmsCode: { type: Function, required: true },
});
const captchaRef = ref(null);
const formRef = ref(null);
const form = reactive({ phone: "", code: "", remember: [] });
const state = reactive({ disabled: false, codeText: "" });

const rules = {
    phone: [
        { required: true, message: "请输入手机号码" },
        {
            validator: async (_, value) =>
                /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/.test(value)
                    ? Promise.resolve()
                    : Promise.reject("手机号格式不正确"),
        },
    ],
    code: [
        { required: true, message: "请输入验证码" },
        { len: 6, message: "请输入6位数验证码" },
    ],
};

const getSmsCodeCallback = (status) => {
    if (status) {
        captchaRef.value.start();
    }
};

const handleGetCode = async () => {
    const checkPhone = await formRef.value.validateField("phone").catch(() => {});
    if (!checkPhone) return;

    if (captchaRef.value.disabled) return;

    const fn = props.getSmsCode(form.phone, getSmsCodeCallback);
    let status = null;

    if (fn instanceof Promise) {
        status = await fn;
        if (status !== void 0) getSmsCodeCallback(status);
    }
};

const handleLogin = async () => {
    const status = await formRef.value.validate().catch(() => {});
    if (!status) return;
    const params = { ...form, remember: Boolean(form.remember.length) };

    emits("login", { type: "phone", params });
};
</script>

<style lang="scss" scoped>
.btn-login {
    width: 100%;
}

:deep() {
    .el-input-group__append {
        flex-grow: 1;
        .el-button.is-link {
            border: none;
            margin: 0;
            padding: 0;
        }
    }
}
</style>
